home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
...taking it to the Macs!
/
...taking it to the Macs!.iso
/
Extras
/
ActiveX Mac SDK
/
ActiveX SDK
/
Control Common
/
CBaseControl.cpp
< prev
next >
Wrap
Text File
|
1996-12-20
|
18KB
|
712 lines
// =================================================================================
//
// CBaseControl.cpp ©1996 Microsoft Corporation All rights reserved.
//
// =================================================================================
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "ocheaders.h"
#include "debug.h"
#include "CBaseControl.h"
#include "register.h"
#include "ResourceMap.h"
#include "dllentry.h"
#define SafeReleaseAndNull(interface) \
if (interface != NULL) { \
interface->Release(); \
interface = NULL; \
}
#define DEFAULT_CONTROL_SIZE 50
#pragma mark === CBaseControl::Construction & Destruction ===
//=--------------------------------------------------------------------------=
// CBaseControl::CBaseControl
//=--------------------------------------------------------------------------=
// Constructor
//
CBaseControl::CBaseControl(void)
{
mUnkOuterP = NULL;
mContainerSiteP = NULL;
mContainerP = NULL;
mActive = false;
mCPContainerP = NULL;
mContextInfo = NULL;
mActiveContext = NULL;
mSize.h = mSize.v = DEFAULT_CONTROL_SIZE;
*mID = 0;
mContextInfo = new LArray(sizeof(CBaseContextInfo*));
DLLAddRef();
}
//=--------------------------------------------------------------------------=
// CBaseControl::~CBaseControl
//=--------------------------------------------------------------------------=
// Destructor
//
CBaseControl::~CBaseControl(void)
{
if (mContextInfo)
{
ArrayIndexT i = LArray::index_First;
CBaseContextInfo* ContextInfoP;
while (mContextInfo->FetchItemAt(i++, &ContextInfoP))
delete ContextInfoP;
delete mContextInfo;
mContextInfo = NULL;
}
StopIdling();
SafeReleaseAndNull(mContainerP);
SafeReleaseAndNull(mContainerSiteP);
SafeReleaseAndNull(mUnkOuterP);
SafeReleaseAndNull(mCPContainerP);
DLLRelease();
}
#pragma mark === CBaseControl::IUnknown ===
//=--------------------------------------------------------------------------=
// CBaseControl::IUnknown::QueryInterface
//=--------------------------------------------------------------------------=
// Returns a pointer to the specified interface on a component to which a
// client currently holds an interface pointer.
//
STDMETHODIMP
CBaseControl::QueryInterface(REFIID inRefID, void** outObj)
{
ErrorCode Result = CBaseCOM::QueryInterface(inRefID, outObj);
if ( Result == E_NOINTERFACE )
{
void* pv = nil;
if ( inRefID == IID_IObjectWithSite )
pv = (void*)(IObjectWithSite* ) this;
else if (inRefID == IID_IControl )
pv = (void*)(IControl*) this;
else if (inRefID == IID_IPersist || inRefID == IID_IPersistPropertyBag)
pv = (void*)(IPersistPropertyBag*) this;
else if (inRefID == IID_IConnectionPointContainer)
{
if ( mCPContainerP )
return mCPContainerP->QueryInterface(IID_IConnectionPointContainer, outObj);
}
*outObj = pv;
// if we got an interface, ref it and return ok
if ( pv )
{
((IUnknown*) pv)->AddRef();
Result = S_OK;
}
}
return Result;
}
#pragma mark === CBaseControl::IObjectWithSite ===
//=--------------------------------------------------------------------------=
// CBaseControl::IObjectWithSite::SetSite
//=--------------------------------------------------------------------------=
// informs the control of it's client site display
// location within it's container
//
STDMETHODIMP
CBaseControl::SetSite(IUnknown* inClientSite)
{
// remove any idlers that have been set up
StopIdling();
// Release the outer unknown
SafeReleaseAndNull(mUnkOuterP);
// Set our outer unknown to the one provided
mUnkOuterP = (IUnknown*) inClientSite;
// if we got a site, get the other interfaces we need.
if (mUnkOuterP != NULL)
{
// Only release these if we get called with a non-null inClientSite
// Should only ever get called with a null client site if the object
// is going away. Then these interfaces get released in the destructor.
SafeReleaseAndNull(mContainerSiteP);
SafeReleaseAndNull(mContainerP);
// Add our reference to the unknown
mUnkOuterP->AddRef();
// Get the IContainerSite interface
mUnkOuterP->QueryInterface(IID_IContainerSite, &mContainerSiteP);
// if we got that, get the IContainer interface
if ( mContainerSiteP )
{
mContainerSiteP->GetContainer(&mContainerP);
if ( mContainerP )
mContainerP->AddRef();
StartIdling();
}
}
return S_OK;
}
//=--------------------------------------------------------------------------=
// CBaseControl::IObjectWithSite::GetSite
//=--------------------------------------------------------------------------=
// obtains a pointer to the controls client site.
//
STDMETHODIMP
CBaseControl::GetSite(REFIID inRefID, void** outSite)
{
if ( inRefID == IID_IUnknown )
*outSite = (void*) mUnkOuterP;
else if ( inRefID == IID_IContainerSite )
*outSite = (void*) mContainerSiteP;
return S_OK;
}
#pragma mark === CBaseControl::IControl ===
//=--------------------------------------------------------------------------=
// CBaseControl::IControl::Draw
//=--------------------------------------------------------------------------=
STDMETHODIMP
CBaseControl::Draw(DrawContext* inContext)
{
if (inContext->DrawAspect != DVASPECT_CONTENT)
return DV_E_DVASPECT;
return S_OK;
}
//=--------------------------------------------------------------------------=
// CBaseControl::IControl::OnContextChange
//=--------------------------------------------------------------------------=
STDMETHODIMP
CBaseControl::OnContextChange(UInt32 inContextID, ContextCommand inCommand)
{
ErrorCode Result = S_OK;
CBaseContextInfo* ContextInfo = GetContextInfoByID(inContextID);
switch ( inCommand )
{
case AddContext:
if (!ContextInfo)
{
if ((ContextInfo = NewContext(inContextID)) != NULL)
mContextInfo->InsertItemsAt(1, 1, &ContextInfo);
else
{
#if BE_STRICT
DebugStr("\pAddContext couldn't get a context info object.");
#endif // BE_STRICT
Result = E_FAIL;
}
}
else
{
#if BE_STRICT
DebugStr("\pAddContext with duplicate ContextID.");
#endif // BE_STRICT
Result = E_FAIL;
}
break;
case RemoveContext:
if (ContextInfo)
{
if (ContextInfo == mActiveContext)
mActiveContext = NULL;
mContextInfo->RemoveItemsAt(1, mContextInfo->FetchIndexOf(&ContextInfo));
delete ContextInfo;
}
else
{
Result = E_FAIL;
#if BE_STRICT
DebugStr("\pRemoveContext on a context the control doesn't have.");
#endif // BE_STRICT
}
break;
case UpdateContext:
if (ContextInfo)
ContextInfo->Update(false);
else
{
Result = E_FAIL;
#if BE_STRICT
DebugStr("\pUpdateContext on a context the control doesn't have.");
#endif // BE_STRICT
}
break;
case ActivateContext:
if (ContextInfo)
{
if (mActiveContext != NULL)
{
CBaseContextInfo* ActiveContextInfo = GetContextInfoByID(inContextID);
if (ActiveContextInfo)
ActiveContextInfo->Deactivate(false);
else
{
Result = E_UNEXPECTED;
#if BE_STRICT
DebugStr("\pCan't deactivate a context left active.");
#endif // BE_STRICT
}
#if BE_STRICT
DebugStr("\pActivateContext before a DeactivateContext.");
#endif // BE_STRICT
}
Result = ContextInfo->Activate(false);
mActiveContext = ContextInfo;
}
else
{
Result = E_FAIL;
#if BE_STRICT
DebugStr("\pActivateContext on a context the control doesn't have.");
#endif // BE_STRICT
}
break;
case DeactivateContext:
if (ContextInfo)
{
if (mActiveContext == ContextInfo)
Result = ContextInfo->Deactivate(false);
else
{
Result = E_UNEXPECTED;
#if BE_STRICT
DebugStr("\pDeactivateContext on an inactive context.");
#endif // BE_STRICT
}
mActiveContext = NULL;
}
else
{
Result = E_FAIL;
#if BE_STRICT
DebugStr("\pDeactivateContext on a context the control doesn't have.");
#endif // BE_STRICT
}
break;
default:
Result = E_FAIL;
break;
}
return Result;
}
//=--------------------------------------------------------------------------=
// CBaseControl::IControl::GetID
//=--------------------------------------------------------------------------=
STDMETHODIMP
CBaseControl::GetID(Int32 inBufferSize, Char8* outID)
{
Int32 IDLen;
Char8* Source;
// if we have an id then us it
if (*mID)
{
IDLen = *mID;
Source = (Char8*)(mID + 1);
}
// otherwise use the hard coded registry name
else
{
Source = kOCXFullUserTypeName;
IDLen = strlen(Source);
}
if (--inBufferSize < IDLen)
IDLen = inBufferSize;
::BlockMove(Source, outID, IDLen);
*(outID + IDLen) = '\0';
return S_OK;
}
//=--------------------------------------------------------------------------=
// CBaseControl::IControl::GetUsedArea
//=--------------------------------------------------------------------------=
STDMETHODIMP
CBaseControl::GetUsedArea(PlatformRegion* outUsedArea)
{
#pragma unused (outUsedArea)
return E_FAIL;
}
//=--------------------------------------------------------------------------=
// CBaseControl:IControl:SetFocus
//=--------------------------------------------------------------------------=
STDMETHODIMP
CBaseControl::SetFocus(FocusCommand inCommand, FocusSet inFocus)
{
#pragma unused (inCommand, inFocus)
return E_FAIL;
}
//=--------------------------------------------------------------------------=
// CBaseControl::IControl::DoMouse
//=--------------------------------------------------------------------------=
STDMETHODIMP
CBaseControl::DoMouse(MouseEventType inMouseET, PlatformEvent* inEvent)
{
#pragma unused (inMouseET, inEvent)
return S_OK;
}
//=--------------------------------------------------------------------------=
// CBaseControl::IControl::DoKey
//=--------------------------------------------------------------------------=
STDMETHODIMP
CBaseControl::DoKey(KeyEventType inKeyET, Char8 inChar, PlatformEvent* inEvent)
{
#pragma unused (inKeyET, inChar, inEvent)
return S_OK;
}
//=--------------------------------------------------------------------------=
// CBaseControl:IControl:DoActivate
//=--------------------------------------------------------------------------=
STDMETHODIMP
CBaseControl::DoActivate(ActivateEventType inActiveET, UInt32 inContextID, PlatformEvent* inEvent)
{
#pragma unused (inContextID, inEvent)
switch (inActiveET)
{
case AppActivate:
case WindowActivate:
mActive = true;
break;
case AppDeactivate:
case WindowDeactivate:
mActive = false;
break;
}
return S_OK;
}
//=--------------------------------------------------------------------------=
// CBaseControl::IControl::DoSystemEvent
//=--------------------------------------------------------------------------=
STDMETHODIMP
CBaseControl::DoSystemEvent(PlatformEvent* inEvent)
{
#pragma unused (inEvent)
return S_OK;
}
//=--------------------------------------------------------------------------=
// CBaseControl::IControl::DoIdle
//=--------------------------------------------------------------------------=
STDMETHODIMP
CBaseControl::DoIdle(Uint32 IdleRefCon)
{
#pragma unused (IdleRefCon)
return S_OK;
}
#pragma mark === CBaseControl::IPersist ===
//=--------------------------------------------------------------------------=
// CBaseControl::IPersist::GetClassID
//=--------------------------------------------------------------------------=
//
STDMETHODIMP
CBaseControl::GetClassID(CLSID* ClassID)
{
#pragma unused (ClassID)
return E_NOTIMPL;
}
#pragma mark === CBaseControl::IPersistPropertyBag ===
//=--------------------------------------------------------------------------=
// CBaseControl::IPersistPropertyBag::InitNew
//=--------------------------------------------------------------------------=
//
STDMETHODIMP
CBaseControl::InitNew(void)
{
// BUGBUG: Maybe do stuff here?
return S_OK;
}
//=--------------------------------------------------------------------------=
// CBaseControl::IPersistPropertyBag::Load
//=--------------------------------------------------------------------------=
//
STDMETHODIMP
CBaseControl::Load(IPropertyBag* PropertyBag, IErrorLog* ErrorLog)
{
Int32 i;
VARIANT v;
v.vt = VT_BSTR;
v.bstrVal = NULL;
// get the starting size
if (PropertyBag->Read("width", &v, ErrorLog) == S_OK && v.bstrVal)
{
::StringToNum((Uchar8*)v.bstrVal + sizeof(Uint32) - 1, &i);
mSize.h = i;
CoTaskMemFree(v.bstrVal);
}
if (PropertyBag->Read("height", &v, ErrorLog) == S_OK && v.bstrVal)
{
::StringToNum((Uchar8*)v.bstrVal + sizeof(Uint32) - 1, &i);
mSize.v = i;
CoTaskMemFree(v.bstrVal);
}
if (PropertyBag->Read("id", &v, ErrorLog) == S_OK && v.bstrVal)
{
Int16 IDLen = *((Uint32*) v.bstrVal);
if (IDLen > 255)
IDLen = 255;
::BlockMove(v.bstrVal + sizeof(Uint32), mID + 1, IDLen);
*mID = IDLen;
CoTaskMemFree(v.bstrVal);
}
return S_OK;
}
//=--------------------------------------------------------------------------=
// CBaseControl::IPersistPropertyBag::Save
//=--------------------------------------------------------------------------=
//
STDMETHODIMP
CBaseControl::Save(IPropertyBag* PropertyBag, BOOL ClearDirty, BOOL SaveAllProperties)
{
#pragma unused (PropertyBag, ClearDirty, SaveAllProperties)
return E_NOTIMPL;
}
#pragma mark === CBaseControl::Protected Methods ===
//=--------------------------------------------------------------------------=
// CBaseControl::InvalAllContexts
//=--------------------------------------------------------------------------=
//
void
CBaseControl::InvalAllContexts()
{
Int16 Index = 1;
DrawContext Context = {BeginPortType};
UInt32 ContextID;
while (GetContextID(Index++, &ContextID))
{
if ( mContainerSiteP->AcquireContext(ContextID, &Context) == S_OK)
{
if (Context.PortType == QDWindowPortType)
::InvalRect(&Context.Location);
mContainerSiteP->ReleaseContext(&Context);
}
}
}
//=--------------------------------------------------------------------------=
// CBaseControl::StartIdling [virtual]
//=--------------------------------------------------------------------------=
//
Boolean8
CBaseControl::StartIdling(void)
{
return false;
}
//=--------------------------------------------------------------------------=
// CBaseControl::StartIdling [virtual]
//=--------------------------------------------------------------------------=
//
Boolean8
CBaseControl::StopIdling(void)
{
if (mContainerSiteP)
return mContainerSiteP->SetIdleTime(RemoveAllIdlers, NULL) == S_OK;
else
return false;
}
//=--------------------------------------------------------------------------=
// CBaseControl::NewContext [virtual]
//=--------------------------------------------------------------------------=
//
CBaseContextInfo*
CBaseControl::NewContext(Uint32 inContextID)
{
return new CBaseContextInfo(this, inContextID);
}
//=--------------------------------------------------------------------------=
// CBaseControl::GetContextID
//=--------------------------------------------------------------------------=
//
Boolean8
CBaseControl::GetContextID(Int16 inIndex, Uint32* outContextID)
{
Boolean8 Result;
CBaseContextInfo* ContextInfo = GetContextInfoByIndex(inIndex);
if ((Result = ContextInfo != NULL) != false)
*outContextID = ContextInfo->GetContextID();
return Result;
}
//=--------------------------------------------------------------------------=
// CBaseControl::GetContextInfoByID
//=--------------------------------------------------------------------------=
//
CBaseContextInfo*
CBaseControl::GetContextInfoByID(Uint32 inContextID)
{
ArrayIndexT Index = LArray::index_First;
CBaseContextInfo* ContextInfo;
while (mContextInfo->FetchItemAt(Index++, &ContextInfo))
if (ContextInfo && ContextInfo->GetContextID() == inContextID)
return ContextInfo;
return NULL;
}
//=--------------------------------------------------------------------------=
// CBaseControl::GetContextInfoByIndex
//=--------------------------------------------------------------------------=
//
CBaseContextInfo*
CBaseControl::GetContextInfoByIndex(Int16 inIndex)
{
CBaseContextInfo* ContextInfo;
if (!mContextInfo->FetchItemAt(inIndex, &ContextInfo))
ContextInfo = NULL;
return ContextInfo;
}
#pragma mark === CBaseContextInfo Construction & Destruction ===
//=--------------------------------------------------------------------------=
// CBaseContextInfo::CBaseContextInfo
//=--------------------------------------------------------------------------=
// Constructor
//
CBaseContextInfo::CBaseContextInfo(CBaseControl* inControlP, Uint32 ContextID)
{
mContextID = ContextID;
mControlP = inControlP;
}
//=--------------------------------------------------------------------------=
// CBaseContextInfo::~CBaseContextInfo
//=--------------------------------------------------------------------------=
// Destructor
//
CBaseContextInfo::~CBaseContextInfo(void)
{
}
#pragma mark === CBaseContextInfo Stub Implementation ===
//=--------------------------------------------------------------------------=
// CBaseContextInfo::Update
//=--------------------------------------------------------------------------=
// Update
//
ErrorCode
CBaseContextInfo::Update(Boolean8 Acquired)
{
#pragma unused (Acquired)
return S_OK;
}
//=--------------------------------------------------------------------------=
// CBaseContextInfo::Activate
//=--------------------------------------------------------------------------=
// Activate
//
ErrorCode
CBaseContextInfo::Activate(Boolean8 Acquired)
{
#pragma unused (Acquired)
return S_OK;
}
//=--------------------------------------------------------------------------=
// CBaseContextInfo::Deactivate
//=--------------------------------------------------------------------------=
// Deactivate
//
ErrorCode
CBaseContextInfo::Deactivate(Boolean8 Acquired)
{
#pragma unused (Acquired)
return S_OK;
}